!function ($) {
    // Definition
    var VisLegend = function (element, options) {
        this.target_el = "#" + element.id;
        if (options) _.extend(this, options);
    };

    VisLegend.prototype = {
        constructor:VisLegend,

        vertical_padding:10,
        horizontal_padding:10,
        label_width:100,
        bar_height:20,
        bar_width:5,
        plot_height:196,
        plot_width:256,
        legend_panel_offset:0,
        data_area_height:0,

        draw:function (legend_data, options) {
            if (options) {
                _.extend(this, options);
            }

            var scale_classes = _.map(legend_data, function (d) {
                return d.cls;
            });

            var legend_scale = d3.scale.ordinal().domain(scale_classes).rangeBands([0, this.plot_height]);

            var vis = d3.select(this.target_el)
                .append("svg")
                .attr("width", this.plot_width + 2 * this.horizontal_padding)
                .attr("height", this.plot_height + 2 * this.vertical_padding);

            var legend_area = vis.append("g")
                .attr("class", "legend")
                .attr("transform", "translate(" + this.horizontal_padding + "," + (this.legend_panel_offset + this.data_area_height) + ")")
                .attr("width", this.plot_width)
                .attr("height", this.plot_height);

            var legend_rows = legend_area.selectAll("g.legend-row")
                .data(legend_data)
                .enter()
                .append("g")
                .attr("class", "legend-row")
                .attr("transform", function (d) {
                    return "translate(0," + legend_scale(d.cls) + ")";
                });

            legend_rows
                .append("text")
                .attr("class", "legend-label")
                .attr("x", 20)
                .attr("y", this.bar_height - 3.0)
                .text(function (d) {
                    return d.label
                });

            legend_rows
                .append("rect")
                .attr("class", function (d) {
                    return d.cls;
                })
                .attr("x", 3.0 * this.label_width)
                .attr("x", 0)
                .attr("y", 0)
                .attr("width", this.bar_width)
                .attr("height", this.bar_height);
        }
    };

    // jQuery Plugin
    $.fn.vislegend = function (data, options) {
        return this.each(function () {
            var $this = $(this);
            var vis = $this.data("VisLegend");
            if (!vis) $this.data("VisLegend", (vis = new VisLegend(this, options)));
            vis.draw(data);
        });
    };
}(window.jQuery);
